package com.icss.trans.send.httpput;

import java.io.File;
import java.io.UnsupportedEncodingException;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;

/**
 * 
 * @ClassName: SendParam
 * @Description:
 * @author ICSS
 * @date 2015-3-25 下午3:09:31
 * 
 */
public class SendParam {

    /**
     * <pre>
     * 请求参数数据项：
     * 1、 dataTransType（数据类型ID）
     * 2、 sourceAppCode（源应用类型ID）
     * 3、 destAppCode（目标应用类型ID）
     * 4、 key （身份识别码），必选
     * 5、 fileName（数据文件名称），必选 
     * 6、md5Str（完整性校验码），必选； 
     * 7、 desc（业务属性描述），可选； 
     * 8、fileInputstream  数据文件流（InputStream对象），必选； 
     * 9、transType（传输类型）必选
     * 10、destOrgCode（ 目标节点组织编码）必选
     * 11、appTransId  业务系统定义的传输标识ID（可选，无值时赋空值）
     * 
     * </pre>
     */

    private String dataTransType; // 数据传输类型

    private String sourceAppCode; // 源应用编码

    private String destAppCode; // 目标应用编码

    private String key; // 身份识别码

    private String fileName; // 文件名称

    private String md5Str; // 完整性校验码

    private String destOrgCode; // 目标节点组织机构编码 ;

    private File fileInputstream; // 文件流

    private String desc; // 业务描述属性

    private String appTransId; // 业务系统定义的传输标识ID 包ID

    private String transType;

    private SendParam(Builder builder) {
        this.dataTransType = builder.dataTransType;
        this.sourceAppCode = builder.sourceAppCode;
        this.destAppCode = builder.destAppCode;
        this.key = builder.key;
        this.fileName = builder.fileName;
        this.md5Str = builder.md5Str;
        this.destOrgCode = builder.destOrgCode;
        this.fileInputstream = builder.fileInputstream;
        this.desc = builder.desc;
        this.appTransId = builder.appTransId;
        this.transType = builder.transType;
    }

    /**
     * @Description: 默认的构造函数
     */
    public SendParam() {
    }

    /**
     * 
     * @ClassName: builder
     * @Description: 构建器
     * @author ICSS
     * @date 2015-4-8 上午11:12:06
     *
     */
    public static class Builder {
        private String dataTransType; // 数据传输类型

        private String sourceAppCode; // 源应用编码

        private String destAppCode; // 目标应用编码

        private String key; // 身份识别码

        private String fileName; // 文件名称

        private String md5Str; // 完整性校验码

        private String destOrgCode; // 目标节点组织机构编码 ;

        private File fileInputstream; // 文件流

        private String desc; // 业务描述属性

        private String appTransId; // 业务系统定义的传输标识ID 包ID

        private String transType;

        /**
         * 
         * @Description: 构建发送参数对象
         * @return
         */
        public SendParam build() {
            if (StringUtils.isEmpty(dataTransType)) {
                throw new IllegalArgumentException("param[dataTransType] is null");
            }
            if (StringUtils.isEmpty(sourceAppCode)) {
                throw new IllegalArgumentException("param[sourceAppCode] is null");
            }
            if (StringUtils.isEmpty(destOrgCode)) {
                throw new IllegalArgumentException("param[destOrgCode] is null");
            }
            if (StringUtils.isEmpty(key)) {
                throw new IllegalArgumentException("param[key] is null");
            }
            if (StringUtils.isEmpty(fileName)) {
                throw new IllegalArgumentException("param[fileName] is null");
            }
            if (null == fileInputstream || !fileInputstream.exists()) {
                throw new IllegalArgumentException("param[fileInputstream] is null or not exits");
            }
            // 如果不设置目标应用代码则默认和原一样
            if (StringUtils.isEmpty(destAppCode)) {
                destAppCode = this.sourceAppCode;
            }
            return new SendParam(this);
        }

        public Builder dataTransType(String dataTransType) {
            this.dataTransType = dataTransType;
            return this;
        }

        
        public Builder sourceAppCode(String sourceAppCode) {
            this.sourceAppCode = sourceAppCode;
            return this;
        }

        
        public Builder destAppCode(String destAppCode) {
            this.destAppCode = destAppCode;
            return this;
        }

        
        public Builder key(String key) {
            this.key = key;
            return this;
        }

        
        public Builder fileName(String fileName) {
            this.fileName = fileName;
            return this;
        }

        
        public Builder md5Str(String md5Str) {
            this.md5Str = md5Str;
            return this;
        }

        
        public Builder destOrgCode(String destOrgCode) {
            this.destOrgCode = destOrgCode;
            return this;
        }

        
        public Builder fileInputstream(File fileInputstream) {
            this.fileInputstream = fileInputstream;
            return this;
        }

        
        public Builder desc(String desc) {
            this.desc = desc;
            return this;
        }

        
        public Builder appTransId(String appTransId) {
            this.appTransId = appTransId;
            return this;
        }

        
        public Builder transType(String transType) {
            this.transType = transType;
            return this;
        }

    }

    public String getDataTransType() {
        return dataTransType;
    }

    public void setDataTransType(String dataTransType) {
        this.dataTransType = dataTransType;
    }

    public String getSourceAppCode() {
        return sourceAppCode;
    }

    public void setSourceAppCode(String sourceAppCode) {
        this.sourceAppCode = sourceAppCode;
    }

    public String getDestAppCode() {
        return destAppCode;
    }

    public void setDestAppCode(String destAppCode) {
        this.destAppCode = destAppCode;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getMd5Str() {
        return md5Str;
    }

    public void setMd5Str(String md5Str) {
        this.md5Str = md5Str;
    }

    public String getDestOrgCode() {
        return destOrgCode;
    }

    public void setDestOrgCode(String destOrgCode) {
        this.destOrgCode = destOrgCode;
    }

    public File getFileInputstream() {
        return fileInputstream;
    }

    public void setFileInputstream(File fileInputstream) {
        this.fileInputstream = fileInputstream;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getAppTransId() {
        return appTransId;
    }

    public void setAppTransId(String appTransId) {
        this.appTransId = appTransId;
    }

    public String getTransType() {
        return transType;
    }

    public void setTransType(String transType) {
        this.transType = transType;
    }

    /**
     * 
     * @Description: 构建上传文件的多部分form表单实体
     * @return
     * @throws UnsupportedEncodingException
     * @throws
     */
    public MultipartEntity buildMultipartEntity() throws UnsupportedEncodingException {
        MultipartEntity reqEntity = new MultipartEntity();
        addPart(reqEntity, "fileName", this.getFileName());
        addPart(reqEntity, "md5Str", this.getMd5Str());
        addPart(reqEntity, "key", this.getKey());
        addPart(reqEntity, "dataTransType", this.getDataTransType());
        addPart(reqEntity, "sourceAppCode", this.getSourceAppCode());
        addPart(reqEntity, "desc", this.getDesc());
        addPart(reqEntity, "destOrgCode", this.getDestOrgCode());
        addPart(reqEntity, "destAppCode", this.getDestAppCode());
        addPart(reqEntity, "appTransId", this.getAppTransId());
        addPart(reqEntity, "transType", this.getTransType());
        addFilePart(reqEntity, "fileInputstream", this.getFileInputstream());
        return reqEntity;
    }

    /**
     * @Description:
     * @param reqEntity
     */
    private void addFilePart(MultipartEntity reqEntity, String param, File value) {
        if (this.getFileInputstream() != null) {
            reqEntity.addPart(param, new FileBody(value));
        }
    }

    private void addPart(MultipartEntity reqEntity, String param, String value) throws UnsupportedEncodingException {
        if (StringUtils.isNotEmpty(value)) {
            reqEntity.addPart(param, new StringBody(value));
        }
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }

}
